#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    fotoNum = 0;
    barrasMax = ui->horizontalSlider->value();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    QString path = QFileDialog::getExistingDirectory();
    QFile valores("readings.bin");
    QDir::setCurrent(path);
    QDataStream in;

    valores.open(QIODevice::ReadOnly);
    in.setDevice(&valores);
    in.setVersion(QDataStream::Qt_4_8);
    medidas.clear();
    ui->horizontalSlider->setEnabled(true);
    ui->HorizSliderFotogramas->setEnabled(true);
    ui->ButtonFotoSig->setEnabled(true);
    ui->ButtonFotoAnterior->setEnabled(true);

    while(!in.atEnd()) {
        QVector<uint32_t> temp;

        in >> temp;

        if (temp.size() < NUM_BYTES) {
            temp.resize(NUM_BYTES);
        }
        medidas.append(temp);
    }

    ui->HorizSliderFotogramas->setMaximum(medidas.size() - 1);
    ui->HorizSliderFotogramas->setValue(0);
    mostrarFoto();
    mostrarDatos();
}

void MainWindow::mostrarFoto()
{
    QString fotoPath(QString().sprintf("%05d", fotoNum) + ".jpg");

    ui->LabelFoto->setPixmap(QPixmap(fotoPath));
}

void MainWindow::mostrarDatos()
{
    QVector<uint32_t> medidaBarras = medidas[fotoNum];
    QList<QObject*> barrasFront;
    QList<QObject*> barrasTras;
    QList<QObject*> barrasHist;

    //Datos recibidos por comunicacion
    uint32_t valoresBarras[40];
    float posLinea;
    float Kp_direccion;
    float Ki_direccion;
    float Kd_direccion;
    float Error_Acumulado_direccion;
    float Error_Anterior_direccion;
    float Kp_gas;
    float Ki_gas;
    float Kd_gas;
    float Error_Acumulado_gas;
    float Error_Anterior_gas;
    uint16_t output_steer;
    uint16_t output_throt;
    uint16_t entradaAux;
    uint32_t Pulsos_Encoder_Total;
    float Velocidad_Pulsos_s;

    //Escribir los valores obtenidos en los indicadores de barras frontales
    barrasFront = ui->FrameBarrasFron->children();
    for(int i = 1; i < barrasFront.size(); i++) {
        uint32_t valorAux;

        valorAux = 0xFF00 & ((uint16_t)medidaBarras[2*(i - 1)] << 8);
        valorAux += medidaBarras[2*i - 1];
        valoresBarras[i - 1] = valorAux;

        ((QProgressBar*)barrasFront[i])->setMaximum(barrasMax);
        ((QProgressBar*)barrasFront[i])->setValue((valorAux > barrasMax) ? barrasMax : valorAux);
    }

    //Escribir los valores obtenidos en los indicadores de barras traseras
    barrasTras = ui->FrameBarrasTras->children();
    for (int i = 1; i < barrasTras.size(); i++) {
        uint32_t valorAux;

        valorAux = 0xFF00 & ((uint16_t)medidaBarras[2*(barrasFront.size() + i - 2)] << 8);
        valorAux += (0xFF & medidaBarras[2*(barrasFront.size() + i) - 3]);
        valoresBarras[barrasFront.size() + i - 2] = valorAux;

        ((QProgressBar*)barrasTras[i])->setMaximum(barrasMax);
        ((QProgressBar*)barrasTras[i])->setValue((valorAux > barrasMax) ? barrasMax : valorAux);
    }

    //Obtener los valores del vector de medidas
    posLinea = *((float *)(&medidaBarras[INDEX_Posicion_Linea]));
    Kp_direccion = *((float *)(&medidaBarras[INDEX_Kp_direccion]));
    Ki_direccion = *((float *)(&medidaBarras[INDEX_Ki_direccion]));
    Kd_direccion = *((float *)(&medidaBarras[INDEX_Kd_direccion]));
    Error_Acumulado_direccion = *((float *)(&medidaBarras[INDEX_Error_Acumulado_direccion]));
    Error_Anterior_direccion = *((float *)(&medidaBarras[INDEX_Error_Anterior_direccion]));
    Kp_gas = *((float *)(&medidaBarras[INDEX_Kp_gas]));
    Ki_gas = *((float *)(&medidaBarras[INDEX_Ki_gas]));
    Kd_gas = *((float *)(&medidaBarras[INDEX_Kd_gas]));
    Error_Acumulado_gas = *((float *)(&medidaBarras[INDEX_Error_Acumulado_gas]));
    Error_Anterior_gas = *((float *)(&medidaBarras[INDEX_Error_Anterior_gas]));
    output_steer = *((uint16_t *)(&medidaBarras[INDEX_output_steer]));
    output_throt = *((uint16_t *)(&medidaBarras[INDEX_output_throt]));
    entradaAux = *((uint16_t *)(&medidaBarras[INDEX_EntradaAux]));
    Pulsos_Encoder_Total = *((uint32_t *)(&medidaBarras[INDEX_Pulsos_Encoder_Total]));
    Velocidad_Pulsos_s = *((float *)(&medidaBarras[INDEX_Velocidad_Pulsos_s]));

    //Escribir los valores
    ui->ResultadoSlider->setValue((int)(posLinea*100));
    ui->KpDir->setText(QString().sprintf("%.2f", Kp_direccion));
    ui->KiDir->setText(QString().sprintf("%.2f", Ki_direccion));
    ui->KdDir->setText(QString().sprintf("%.2f", Kd_direccion));
    ui->EAcDir->setText(QString().sprintf("%.2f", Error_Acumulado_direccion));
    ui->EAnDir->setText(QString().sprintf("%.2f", Error_Anterior_direccion));
    ui->KpThrot->setText(QString().sprintf("%.2f", Kp_gas));
    ui->KiThrot->setText(QString().sprintf("%.2f", Ki_gas));
    ui->KdThrot->setText(QString().sprintf("%.2f", Kd_gas));
    ui->EAcThrot->setText(QString().sprintf("%.2f", Error_Acumulado_gas));
    ui->EAnThrot->setText(QString().sprintf("%.2f", Error_Anterior_gas));
    ui->PulsosTotales->setText(QString().sprintf("%d", Pulsos_Encoder_Total));
    ui->Velocidad->setText(QString().sprintf("%.2f", Velocidad_Pulsos_s));

    if (output_steer > 0) {
        ui->progressBar_salidadir_der->setValue(output_steer);
        ui->progressBar_salidadir_izq->setValue(0);
    }else {
        ui->progressBar_salidadir_izq->setValue(output_steer);
        ui->progressBar_salidadir_der->setValue(0);
    }

    if (output_throt > 0) {
        ui->progressBar_salidaGas_acel->setValue(output_steer);
        ui->progressBar_salidaGas_Fren->setValue(0);
    }else {
        ui->progressBar_salidaGas_Fren->setValue(output_steer);
        ui->progressBar_salidaGas_acel->setValue(0);
    }

    //    ui->ResultadoSlider->setValue();
    //    ui->HayBifurcacion->setChecked(miDecision.hayBifurcacion());
    //    ui->HayLinea->setChecked(miDecision.getHayLinea());
    //    *valorHist = miHistograma.getHistograma();

    //    barrasHist = ui->histogramFrame->children();
    //    for (int i = 1; i < barrasHist.size(); i++) {
    //        ((QProgressBar*)barrasHist[i])->setValue((int)(valorHist[i-1]*100));
    //    }
}

void MainWindow::on_horizontalSlider_valueChanged(int value)
{
    barrasMax = value;
    mostrarDatos();
}

void MainWindow::on_ButtonFotoAnterior_clicked()
{
    if (fotoNum > 0) {
        fotoNum--;
        ui->HorizSliderFotogramas->setValue(fotoNum);
        mostrarFoto();
        mostrarDatos();
    }
}

void MainWindow::on_ButtonFotoSig_clicked()
{
    if (fotoNum < (medidas.size() - 1)) {
        fotoNum++;
        ui->HorizSliderFotogramas->setValue(fotoNum);
        mostrarFoto();
        mostrarDatos();
    }
}

void MainWindow::on_HorizSliderFotogramas_valueChanged(int value)
{
    fotoNum = value;
    mostrarFoto();
    mostrarDatos();
}
